﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WXDba.Entity;
using WXDba.Abstract;
namespace WXPackage
{
    /// <summary>
    /// 用户管理操作
    /// </summary>
    public class UserManage : BaseManage
    {
        IWXUser _IWXUser = ConcreteFactory.GetWXUser();

        #region 同步操作
        /// <summary>
        /// 同步账号用户的OpenID，和本地数库
        /// </summary>
        public int SyncOpenID()
        {
            int allCount = 0;
            LoadOpenID_Remove((idList, total, currentCount) =>
            {
                allCount += currentCount;
                //将当前获取的所有openid 添加到数据,如果当前OpenID不存在
                _IWXUser.AddOpenIDList(idList);
            });
            return allCount;
        }
        /// <summary>
        /// 同步当前所有用户信息，根据OpenID
        /// </summary>
        /// <returns></returns>
        public int SyncUserInfo()
        {
            int current = 0;
            //1.遍历获取OpenID 列表
            _IWXUser.ForeachOpenID((idList) =>
            {
                //2.远程获取用户基本信息
                List<WXUser> userList = LoadList_Remove(idList);
                //循环添加或修改用户信息
                foreach (var user in userList)
                {
                    if (_IWXUser.AddOrUpdate(user))
                        current++;
                }
            });
            return current;
        }
        /// <summary>
        /// 修改用户的备注名称
        /// </summary>
        /// <param name="OpenID">OpenID</param>
        /// <param name="Remark">备注内容小于30字符</param>
        /// <returns></returns>
        public bool UpdateRemark(string OpenID, string Remark)
        {
            if (string.IsNullOrEmpty(Remark))
                throw new Exception("修改备注名称时，备注不能为空");
            if (Remark.Length >= 30)
                throw new Exception("备注名称需要小于30字符");

            string url = new LinkManage().GetUser_UpdateRemark();
            string result = NetHelper.Post(url, new { openid = OpenID, remark = Remark }.ToJsonString());
            JObject obj = JObject.Parse(result);
            if ((string)obj["errmsg"] == "ok")
            {
                //修改本地数据库
                _IWXUser.UpdateRemark(OpenID, Remark);
                return true;
            }
            throw new Exception("修改备注失败，返回内容：" + result);
        }
        #endregion

        #region 加载远程数据
        /// <summary>
        /// 加载所有的关注用户OpenID
        /// </summary>
        /// <param name="onSuccess">每次获取成功后触发</param>
        /// <returns></returns>
        public int LoadOpenID_Remove(Action<List<String>, int, int> onSuccess)
        {
            int allCount = 0;
            string next_openid = string.Empty;
            try
            {
                while (true)
                {
                    string url = new LinkManage().GetUserList(next_openid);
                    //获取请求
                    string result = NetHelper.Get(url);
                    OpenIDData _data = JsonConvert.DeserializeObject<OpenIDData>(result);
                    if (_data == null)
                        throw new Exception(result);
                    allCount += _data.Count;
                    next_openid = _data.Next_OpenID;
                    //获取数据成功
                    if (onSuccess != null)
                        onSuccess(_data.GetOpenIDList(), _data.Total, allCount);
                    //结束循环
                    if (allCount >= _data.Total)
                        break;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("获取OpenID列表异常，" + ex.Message + ",当前allCount=" + allCount);
            }
            return allCount;
        }
        /// <summary>
        /// 指定OpenID，加载用户信息
        /// </summary>
        /// <param name="OpenID"></param>
        /// <returns></returns>
        public WXUser LoadInfo_Remove(string OpenID)
        {
            try
            {
                string url = new LinkManage().GetUserInfo(OpenID);
                string result = NetHelper.Get(url);
                if (string.IsNullOrEmpty(result))
                    throw new Exception("返回结果为空");
                WXUser user = JsonConvert.DeserializeObject<WXUser>(result);
                if (user == null)
                    throw new Exception("反序列化失败");
                return user;
            }
            catch (Exception ex)
            {
                throw new Exception("获取用户信息失败，OpenID=" + OpenID + "," + ex.Message);
            }
            return null;
        }
        /// <summary>
        /// 批量获取用户基本信息
        /// </summary>
        /// <param name="idList">指定OpenID列表，不能超过100</param>
        /// <returns></returns>
        public List<WXUser> LoadList_Remove(List<string> idList)
        {
            List<WXUser> list = new List<WXUser>();
            try
            {
                if (idList.Count > 100)
                    throw new Exception("一次获取的个数不能超过100");
                string url = new LinkManage().GetUserInfo();
                JArray array = new JArray();
                foreach (var item in idList)
                {
                    array.Add(JToken.FromObject(new { openid = item, lang = "zh-CN" }));
                }
                var param = JObject.FromObject(new { user_list = array }).ToString();
                //提交获取数据
                string result = NetHelper.Post(url, param);
                JObject obj = JObject.Parse(result);
                //string strList = (string)obj.SelectToken("user_info_list");
                //JToken temp= obj.SelectToken("user_info_list");
                //list = JsonConvert.DeserializeObject<List<WXUser>>(temp);

                string strList = obj.SelectToken("user_info_list").ToString();
                list = JsonConvert.DeserializeObject<List<WXUser>>(strList);
            }
            catch (Exception ex)
            {
                throw new Exception("批量获取用户基本信息失败，" + ex.Message);
            }
            return list;
        }
        #endregion

        /// <summary>
        /// 获取用户OpenID 返回结果
        /// </summary>
        public class OpenIDData
        {
            /// <summary>
            /// 关注改公众号的总用户数
            /// </summary>
            public int Total { get; set; }
            /// <summary>
            /// 当前获取的OPENID个数，最大值10000
            /// </summary>
            public int Count { get; set; }
            /// <summary>
            /// OpenID的列表
            /// </summary>
            public JObject Data { get; set; }
            /// <summary>
            /// 拉去列表的最后一个用户OpenID
            /// </summary>
            public string Next_OpenID { get; set; }

            public List<string> GetOpenIDList()
            {
                JObject obj = this.Data;
                JToken token = obj.SelectToken("openid");
                if (token == null)
                    return new List<string>();
                return token.Select(q => (string)q).ToList();
            }
        }
    }
}
